﻿// Extensions Made Easy - Copyright 2012 by Jan Van der Haegen - All rights reserved, use for educational purposes only.
using System;
using System.ComponentModel.Composition;
using ExtensionsMadeEasy.ClientAPI.Utilities.Extensions;
using Microsoft.LightSwitch.Details;
using Microsoft.LightSwitch.Runtime.Shell.ViewModels.Navigation;
using Microsoft.LightSwitch.Threading;

namespace ExtensionsMadeEasy.Navigation
{
    [Export(typeof(IScreenOpener))]
    public sealed class ScreenOpener : IScreenOpener
    {
        public bool NavigateTo(string screen)
        {
            if (string.IsNullOrEmpty(screen))
            {
                return false;
            }
            bool result = false;
            string linkName = screen.ToLower().Replace(" ", "");

            INavigationScreen link = this.FindLink(linkName);
            if (null != link)
            {
                // Execute the command by obtaining the dispacther and invoking
                // the execute method in the correct thread context.
                IBusinessCommand businessCommand = (IBusinessCommand)link.ExecutableObject;
                IDispatcherObject dispatcher = businessCommand;
                dispatcher.Dispatcher.BeginInvoke(delegate()
                {
                    if (businessCommand.CanExecute)
                    {
                        businessCommand.Execute();
                    }
                    else
                    {
                        result = false;
                    }
                });
                result = true;
            }
            else
            {
                result = false;
            }

            return result;
        }

        private INavigationScreen FindLink(string name)
        {
            // Recursively descend into the navigation object model to find the
            // navigation item with the specified name.
            INavigationScreen link = null;

            // foreach (INavigationItem navItem in this.AllItems)
            foreach (INavigationItem navItem in this.GetServiceProxy().NavigationViewModel.NavigationItems)
            {
                if (navItem is INavigationGroup)
                {
                    link = this.FindLink((INavigationGroup)navItem, name);
                }
                else if (navItem is INavigationScreen)
                {
                    if (this.isMatch((INavigationScreen)navItem, name))
                    {
                        link = (INavigationScreen)navItem;
                    }
                }
                if (null != link)
                {
                    break;
                }
            }
            return link;
        }

        private bool isMatch(INavigationScreen navigationScreen, string name)
        {
            return this.isMatch(navigationScreen.Description, name) ||
                   this.isMatch(navigationScreen.DisplayName, name) ||
                   this.isMatch(navigationScreen.Id, name);
        }
        private bool isMatch(string str1, string str2)
        {
            str1 = str1.Replace(" ", "");
            return String.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);
        }
        private INavigationScreen FindLink(INavigationGroup navGroup, string name)
        {
            INavigationScreen link = null;
            foreach (INavigationItem navItem in navGroup.Children)
            {
                if (navItem is INavigationGroup)
                {
                    link = this.FindLink((INavigationGroup)navItem, name);
                }
                else if (navItem is INavigationScreen)
                {
                    if (this.isMatch((INavigationScreen)navItem, name))
                    {
                        link = (INavigationScreen)navItem;
                    }
                }
                if (null != link)
                {
                    break;
                }
            }
            return link;
        }
    }
}